#ifndef GAME_H
#define GAME_H

#include "base.h"
#include "gfx.h"
#include "io.h"
#include "main.h"

typedef struct
{
    int color;

    int in_use;
    // angle of the paddle (radians)
    float angle;
    // rotation speed (radians/sec)
    float speed;
    // length of the paddle (pixels)
    int size;
    // score of the paddle
    int score;
    // count the number of enemy ball hits
    int count_enemy;
} Paddle;

typedef struct
{
    int color;

    int in_use;
    // radius of the ball (pixels)
    float radius;
    // position (pixels)
    vec2 position;
    // speed (pixels)
    vec2 speed;
} Ball;

typedef struct
{
    int color;

    int in_use;

    vec2 p1;
    vec2 p2;
} Obstacle;

/**
 * \brief Simulate physics for a tick.
 * \param dTime Duration of the tick, in seconds.
 * \return 1 if the game was paused, 0 otherwise.
 */
int game_tick(float dTime);

void game_draw(void);

/**
 * \brief Launch the game loop (simulating+drawing 'till it stops).
 */
void game_mainloop(void);

/**
 * \brief Initialize the game.
 * \warning Call game_set_nb_of_players before.
 */
void game_init(void);

/**
 * \brief Uninitialize the game.
 */
void game_exit(void);

void game_pause(void);

int game_detect_end(void);
void game_over(void);

/**
 * \brief Draw the arena of the game.
 */
void game_draw_field(void);

Paddle* game_get_paddle(int paddle);
void game_set_nb_of_players(int paddle);
int  game_get_nb_of_players(void);
void game_draw_paddle(Paddle *paddle);
void game_set_paddle_off(void);
void game_draw_all_paddles(void);

Ball* game_create_ball(void);
void game_add_ball_for_paddle(Paddle *paddle, Ball *ball);
void game_del_ball_for_paddle(Ball *ball);
Ball* game_get_ball(int ball);
void game_draw_ball(Ball *ball);
void game_draw_all_balls(void);

/**
 * \brief Check if a paddle and a ball collide, and calculate the bounce.
 * \param paddle Pointer to the paddle.
 * \param ball Pointer to the ball.
 * \param new_speed New speed of the ball, if there is a collision.
 * \param new_pos New position of the ball, if there is a collision.
 * \return 1 on collide, 0 otherwise.
 */
int game_collide_paddle_ball(Paddle *paddle, Ball *ball, vec2 new_speed, vec2 new_pos);

/**
 * \brief Check if a segment and a ball collide, and calculate the bounce.
 * \param p1 First point of the segment.
 * \param p2 Second point of the segment.
 * \param new_speed New speed of the ball, if there is a collision.
 * \param new_pos New position of the ball, if there is a collision.
 * \return 1 on collide, 0 otherwise.
 */
int game_collide_segment_ball(vec2 p1, vec2 p2, Ball *ball, vec2 new_speed, vec2 new_pos);

void game_collide_paddles_event(void);
void game_collide_paddle_update(int i, int j);
void game_collide_obstacles(void);
void game_collide_field(Ball *ball);

/**
 * \brief Set the current level and generate the obstacles.
 * \param level New level.
 */
void game_set_level(int level);
int game_get_level(void);

Obstacle* game_get_obstacle(int obstacle);
void game_draw_obstacle(Obstacle *obstacle);
void game_draw_all_obstacles(void);

int game_load_level(int level);
void game_save_level(int level);

void game_draw_interface(void);

#endif
